/*================================================================
*   Copyright (C) 2022 Sangfor Ltd. All rights reserved.
*   
*   文件名称：oj_server.cpp
*   创 建 者：wudu
*   创建日期：2022年03月30日
*   描    述：
*
================================================================*/


#include <iostream>

#include "httplib.h"
#include <json/json.h>

#include "oj_model.hpp"
#include "oj_view.hpp"
#include "oj_compile.hpp"

int main(){
    using namespace httplib;
    Server svr;
    OjModel model;

    //1.获取全部试题信息的接口-Get
    svr.Get("/all_questions", [&model](const Request& req, Response& resp){
                printf("/all_questions\n");
                //1.调用试题模块的函数， 获取全部试题信息
                vector<Question> vec;
                model.GetAllQuetion(vec);

                //2.渲染html页面， 获取html字节流
                string html;
                OjView::DrawAllQuestionHtml(vec, &html);

                resp.set_content(html, "text/html");
            });
    
    //2.获取单个试题信息的接口-Get
    /*
     * 正则表达式：
     * \d : 表示一位数字
     * \d+ : 表示多位数字
     * */
    svr.Get(R"(/question/(\d+))", [&model](const Request& req, Response& resp){
                printf("/question\n");
                //1.区分浏览器到底想要获取的是哪一个题目的信息
                Question ques;
                model.GetOneQuestion(req.matches[1].str(), &ques);

                string html;
                OjView::DrawOneQuestionHtml(ques, &html);
                resp.set_content(html, "text/html");
            });
    
    //3.编译运行的接口-Post
    svr.Post(R"(/compile/(\d+))", [&model](const Request& req, Response& resp){
                //1.切分正文内容 & 进行了urldecode
                unordered_map<string, string> body_kv;
                UrlUtil::PraseBody(req.body, &body_kv);

                //2.查看下题目当中的题目预定义的尾部信息
                Question ques;
                model.GetOneQuestion(req.matches[1].str(), &ques);
                
                //3.组合用户提交的代码 + 预定义的尾部信息
                Json::Value req_json;
                req_json["code"] = body_kv["code"] + ques.tail_cpp_;
                req_json["stdin"] = body_kv["stdin"];

                cout << req_json["code"].asString() << endl;
                //4.调用编译运行模块的接口
                Json::Value resp_json;
                Compiler::CompileAndRun(req_json, resp_json);
                
                //5.回复响应
                string html;
                OjView::DrawCaseResultHtml(resp_json, &html);
                resp.set_content(html, "text/html");
            });

    LOG(INFO, "process start success..., listen port is 18989\n");
    svr.set_base_dir("./www");
    svr.listen("0.0.0.0", 18989);
    return 0;
}
